<?php

declare(strict_types=1);

namespace app\model\base;

use app\common\facade\auth\Auth;
use app\common\service\auth\AuthAgentService;
use app\common\service\auth\AuthOpenService;
use app\common\service\auth\AuthYmshService;
use app\event\ClearCouponH5CacheSuccess;
use app\model\Agent;
use app\Query;
use think\facade\Cache;
use think\facade\Log;
use think\Model;

/**
 * 
 *
 * @mixin \think\Model
 * @method static \app\model\base\Query orderByDesc()
 * @method static \app\model\base\Query AgentId()
 * @property-read \app\model\Agent $agent // * @method static \think\db\Query agentId()
 * @method static \think\db\Query agentId()
 */
class CommonModel extends Model
{
    // 定义软删除字段
    //protected $defaultSoftDelete = 0;
    protected $createTime = 'created_at';
    protected $updateTime = 'updated_at';
    protected $deleteTime = 'deleted_at';
    protected $autoWriteTimestamp = 'datetime';

    public static function getInstance(): self
    {
        return new static();
    }

    public static function query(array $scope = [])
    {
        return self::getInstance()->db($scope);
    }


    /**
     * 查找，如果不存在则创建  有values 则保存
     * @param array $data
     * @return CommonModel|array|mixed|Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function findOrCreate(array $data, $values = [],$is_cache = false)
    {
        $allData = array_merge($data, $values);

        $class = get_called_class();
        $cache_key = 'findOrCreate'.$class.implode('',$allData);
        if ($is_cache) {
            if($newObj = Cache::get($cache_key)) {
                return $newObj;
            }
        }
        $res = self::where($data)->find();

        if (!empty($values) && !empty($res)) {
            $res->save($values);
        }
        if ($res) return $res;

        $class = get_called_class();


        $newObj = new $class();

        $newObj->save($allData);
        Cache::set($cache_key, $newObj,24*3600);
        return $newObj;
    }

    /**
     * 查找，如果不存在则创new一个，需要save才保存
     * @param array $data
     * @return CommonModel|array|mixed|Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function findOrNew(array $data)
    {
        $res = self::where($data)->find();
        if ($res) return $res;
        $class = get_called_class();
        $newObj = new $class($data);
        return $newObj;
    }

    public function scopeOrderByDesc($query)
    {
        /**
         * @var \think\db\Query $query
         */
        $table = !empty($this->table) ? $this->table . '.' : '';
        $query->order($table . 'id', 'desc');
    }

    public function agent()
    {
        return $this->hasOne(Agent::class, 'id', 'agent_id');
    }

    /**
     * 搜索代理商商名称
     * @param $query
     * @param $value
     * @param $params
     */
    public function searchAgentNameAttr($query, $value, $params)
    {
        $table_name = $this->table ? $this->table . '.' : '';

        $agent_name = $params['agent_name'] ?? '';

        $query->when($agent_name, function ($query) use ($agent_name, $table_name) {
            /**
             * @var Query $query
             */
            $query->where($table_name . 'agent_id', 'in', function ($db) use ($agent_name) {
                /**
                 * @var Query $db
                 */
                $db->name('agent')->field('id')
                    ->where('company_name', "$agent_name")
                    ->whereOr('username', "$agent_name");
            });
        });


    }

    /**
     * 搜索订单
     * @param $query
     * @param $value
     * @param $params
     */
    public function searchOrderIdAttr($query, $value, $params)
    {
        $order_id = $params['order_id'] ?? '';
        $table_name = $this->table ? $this->table . '.' : '';
        $query->when($order_id, function ($query) use ($order_id, $table_name) {

            /**
             * @var Query $query
             */
            $query->where(function ($query) use ($order_id, $table_name) {

                $query->where('order_id', 'like', '%' . $order_id . '%');
                $query->whereOr('supplier_order_sn', 'like', '%' . $order_id . '%');
                $query->whereOr('out_order_id', 'like', '%' . $order_id . '%');
            });
//            $query->whereLike('order_id', "%$order_id%");
        });
    }

    /**
     * @param $value
     * @param $params
     * @var Query $query
     */
    public function searchAppIdAttr($query, $value, $params)
    {

        if (empty($value)) return;
        $table_name = $this->table ? $this->table . '.' : '';
        $query->when($value, function ($query) use ($value, $table_name) {
            /**
             * @var Query $query
             */
            $query->where($table_name . 'agent_id', 'in', function ($db) use ($value) {
                /**
                 * @var Query $db
                 */
                $db->name('agent')->field('id')->where('app_id', $value);
            });
        });
    }

    /**
     * @param $value
     * @param $params
     * @var Query $query
     */
    public function searchMerchantIdAttr($query, $value, $params)
    {

        $table_name = $this->table ? $this->table . '.' : '';
        if (empty($value)) return;

        $query->when($value, function ($query) use ($value, $table_name) {
            /**
             * @var Query $query
             */
            $query->where($table_name . 'agent_id', 'in', function ($db) use ($value) {
                /**
                 * @var Query $db
                 */
                $db->name('agent')->field('id')->where('merchant_id', $value);
            });
        });
    }


    /**
     * @param $value
     * @param $params
     * @var Query $query
     */
    public function searchSupplierNameAttr($query, $value, $params)
    {

        if (empty($value)) return;

        $query->when($value, function ($query) use ($value) {
            /**
             * @var Query $query
             */
            $query->where('supplier_id', 'in', function ($db) use ($value) {
                /**
                 * @var Query $db
                 */
                $db->name('base_supplier')->field('id')->whereLike('name', "%$value%");
            });
        });
    }


    public function scopeAgentId($query)
    {
        /**
         * @var \think\db\Query $query
         */
        $auth = Auth::instance();

        $table_name = $this->table ? $this->table . '.' : '';


        /**
         * 开放平台
         */
        if ($auth instanceof AuthOpenService  || $auth instanceof AuthAgentService) {

            $agent_id = Auth::agentId();
            $query->where($table_name . 'agent_id', $agent_id);
        }

        //如果是有美生活请求
        if ($auth instanceof AuthYmshService) {



            Log::info('有美生活鉴权请求统一订单');
            $existAgent = false;

            if (Auth::isAdmin() && Auth::allBindAgentIds()) {
                $query->where($table_name . 'agent_id', 'in', function ($sql) {
                    $sql->name('agent')->field('id')->where('merchant_id', '<>', null)
                        ->where('is_relation', 1);
                });
                $existAgent = true;
            }

            /**
             * @var AuthYmshService
             */
            if (Auth::isMerchant() && Auth::allBindAgentIds()) {

                $query->where($table_name . 'agent_id', 'in', function ($sql) {
                    $sql->name('agent')->field('id')
                        ->where('merchant_id', Auth::merchantId())
                        ->where('is_relation', 1);
                });

                $existAgent = true;
            }

            //如果都不存在绑定的，则一定不给有美生活订单数据
            if (!$existAgent) $query->where($table_name.'agent_id', -2); //一定不成立
        }
    }
    //新增和更新操作会触发
    public static function onAfterWrite(Model $model)
    {
        self::getInstance()->triggerEvent($model);
    }

    //删除操作会触发
    public static function onAfterDelete(Model $model)
    {
        self::getInstance()->triggerEvent($model);
    }

    private function triggerEvent($model)
    {
        //获取模型名称
        $class = get_called_class();
        $modelName = $model->name;
        $modelArr = [
            'app\model\CouponCate',             //todo 商品分类
            'app\model\CouponBrand',            //todo 品牌管理
            'app\model\CouponProductChannel',   //todo 会员直充商品
            'app\model\CouponConfig',           //todo 溢价变动
            'app\model\Config',                 //todo 权益全局副标题显示方式coupon-brand_subtitle 1、2
            'app\model\AgentConfig'             //todo 代理溢价自定义还是默认方式
        ];
        if (in_array($class,$modelArr)) {
            event(new ClearCouponH5CacheSuccess($model, $modelName));
        }
    }


}
